PyInstaller
Install PyInstaller from PyPI:1
pip install pyinstaller
Go to your program’s directory and run:1
pyinstaller yourprogram.py
This will generate the bundle in a subdirectory called dist.
打包过程中可能问题
OSError: Python library not found: Python, libpython3.5m.dylib, libpython3.5.dylib, .Python
python在安装pyenv时没有执行–enabled-shared。重新安装即可1
2
3
4
5
6
7
8# 检查
echo ${PYENV_ROOT}/versions/3.5.5/Python.framework
# 更新
env PYTHON_CONFIGURE_OPTS="--enable-shared" pyenv install 3.5.5
# 重新打包
pyinstaller --onefile p.py
成功输出
只生成一个可执行文件1
pyinstaller --onefile addup.py
ImportError: No module named ‘model’
1 | pyinstaller xxx.py -F --hidden-import fasttext.model |
importerror cannot import name xxx
Make sure everything is packaged correctly
看错误输出里出现了什么包没有引用,加进--hidden-import
里
python路径
os.path.realpath(file)——返回真实路径
os.path.split()——返回路径的目录和文件名
os.getcwd()——得到当前工作的目录1
2
3
4import os
print(os.path.realpath(__file__))
print(os.path.split(os.path.realpath(__file__)))
print(os.getcwd())
将资源文件一起打包
示例1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#coding:utf-8
import sys
import os
#生成资源文件目录访问路径
def resource_path(relative_path):
if getattr(sys, 'frozen', False): #是否Bundle Resource
base_path = sys._MEIPASS
#当使用PyInstaller打包程序选择的是单文件夹打包,PyInstaller会将文件夹的路径信息存储在sys.MEIPASS中。当使用的是单文件打包的方式,sys.MEIPASS的值就是程序运行时创建_MEIxxxxxx临时目录的绝对路径。
else:
base_path = os.path.abspath(".")
#本地测试,直接加入目录。 (".") 换成 (__file__) 也可以
print(base_path)
return os.path.join(base_path, relative_path)
#访问res文件夹下a.txt的内容
filename = resource_path(os.path.join("res", "a.txt"))
print(filename)
with open(filename) as f:
lines = f.readlines()
print(lines)
f.close()
生成.spec
文件1
pyi-makespec -F restest.py
修改datas选项。
它说明需要将哪些文件加入exe,以及在零时文件夹中的命名
注意参数为tuples格式
生成EXE文件
1 | pyinstaller -F test.spec |
总结
pyi-makespec fee_test.py --hidden-import fasttext.fasttext -F
生成.spec
文件- 在
.spec
文件中修改datas
项 pyinstaller fee_test.spec